
struct User {
    name: String, // 逗号，不是C++的分号
    email: String,
    count: u64,
    active: bool
} // 结束处不需要分号

// 元组结构体
struct Color(u32, u32, u32);

#[derive(Debug)]
struct Rect {
    width: u32,
    height: u32
}

impl Rect {
    fn area(&self) -> u32 {
        self.width * self.height
    }

    fn include(&self, other: &Rect) -> bool {
        self.width > other.width && self.height > other.height
    }
}

// 同一struct，可以多个 impl块
impl Rect {
    // 不带 self参数的函数，称为关联函数
    fn new(width:u32, height: u32) -> Rect {
        Rect{width, height}
    }

    // 关联函数，创建正方形
    fn square(size: u32) -> Rect {
        Rect{width:size, height: size}
    }

}

fn main() {
    println!("Hello, struct!");

    let u1 = User {
        name: String::from("lxq"), // k/v
        email: String::from("xqlin@qq.com"),
        count: 123,
        active: true
    };
    println!("name = {}, count = {}", u1.name, u1.count); // 点号访问成员

    let mut u2 = create_user(String::from("weetgo"), String::from("lxq@weetgo.com"));
    print_user(&u2);
    u2.email = u1.email; // 复杂类型，因此u1.email所有权发生了转换。
    print_user(&u2);

    // .. 语法指定了剩余未显式设置值的字段应有与给定实例对应字段相同的值。
    let u3 = User {
        name: String::from("Melody"),
        ..u2
    };
    print_user(&u3);    

    let red = Color(255, 0, 0);
    // 元组结构通过索引获取值，或解构
    println!("Color is R = {} G = {} B = {}", red.0, red.1, red.2);

    let rc = Rect::new(3, 4);
    println!("rect is {:?}", rc);
    println!("Rect's area is {}", rc.area());
    let squre = Rect::square(5);
    println!("rc1 is include in square? {}", squre.include(&rc))

}

fn print_user(user: &User) {
    println!("User {}'s email is {}.", user.name, user.email)
}

fn create_user(name: String, email: String) -> User {
    User {
        name, // 变量与字段同名的简化初始化写法
        email,
        count: 12,
        active: true
    }
}
